/**
 * 
 */
package org.youisoft.summer.evaluator.util;

import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.apache.commons.lang.math.NumberUtils;
import org.youisoft.summer.evaluator.EvalConst;
import org.youisoft.summer.evaluator.OpEnum;
import org.youisoft.summer.evaluator.PlaceHolder;
import org.youisoft.summer.evaluator.operator.Operator;
import org.youisoft.summer.evaluator.operator.base.ClassOperator;
import org.youisoft.summer.evaluator.operator.base.ListOperator;
import org.youisoft.summer.evaluator.operator.base.MapOperator;
import org.youisoft.summer.evaluator.operator.base.NumberOperator;
import org.youisoft.summer.evaluator.operator.base.ObjectOperator;
import org.youisoft.summer.evaluator.operator.base.OperateOperator;
import org.youisoft.summer.evaluator.operator.base.StringOperator;
import org.youisoft.summer.evaluator.unit.Brace;
import org.youisoft.summer.evaluator.unit.Bracket;
import org.youisoft.summer.evaluator.unit.Parenthesis;
import org.youisoft.summer.evaluator.unit.VisitorUnit;

/**
 * @author zijiang.jl
 *
 */
public final class Ulitity {
	private static final java.util.Map<Class<?>, Class<?>> clazzMap=new java.util.HashMap<Class<?>, Class<?>>();
	static {
		clazzMap.put(byte.class, Byte.class);
		clazzMap.put(short.class, Short.class);
		clazzMap.put(int.class, Integer.class);
		clazzMap.put(long.class, Long.class);
		clazzMap.put(float.class, Float.class);
		clazzMap.put(double.class, Double.class);
	}
	private Ulitity(){
		
	}
	
	static class A<T>{
		T t;

		public final T getT() {
			return t;
		}

		public final void setT(T t) {
			this.t = t;
		}
		
	}
	static class B{
		
	}

	public static void main(String[] args) {
		

	}
	
	public void w(int... a){
	}
	
	

	
	public static Class<?> translateClass(Class<?> clazz){
		return clazzMap.get(clazz)!=null?clazzMap.get(clazz):clazz;
	}

	public static Operator<?> smartWrapResource(Object obj){
		if(obj==null){
			return Operator.nullInstance;
		}else if(obj instanceof Operator<?>){
			return (Operator<?>)obj;
		}else if(obj instanceof String){
			return wrapResource(obj.toString().trim());
		}else if(obj instanceof Number){
			return new NumberOperator(Number.class.cast(obj));
		}else if(obj instanceof Boolean){
			Boolean bl=Boolean.class.cast(obj);
			if(bl.booleanValue()) return new NumberOperator(1);
			return new NumberOperator(0);
		}else if(obj.getClass().isArray()){
			
			
		}else if(obj instanceof List<?>){
			List<?> list=(List<?>)obj;
			ListOperator<Operator<?>> co=new ListOperator<Operator<?>>();
			for(int i=0;i<list.size();i++){
				co.addOperator(smartWrapResource(list.get(i)));
			}
			return co;
		}else if(obj instanceof Map<?,?>){
			Map<?,?> map=(Map<?,?>)obj;
			MapOperator<Operator<?>> mo=new MapOperator<Operator<?>>();
			for(java.util.Iterator<?> it=map.keySet().iterator();it.hasNext();){
				Object tmp=it.next();
				mo.putOperator(smartWrapResource(tmp),smartWrapResource(map.get(tmp)));
			}
			return mo;
		}
		ObjectOperator<Object> oo=new ObjectOperator<Object>();
		oo.setValue(obj);
		return oo;
	}


	
	private static Operator<?> wrapResource(String str){
		if(str.indexOf(PlaceHolder.instance.getSplitPlaceHolder())!=-1){
			String[] temp=str.split(PlaceHolder.instance.getSplitPlaceHolder());
			ListOperator<Operator<?>> lo=new ListOperator<Operator<?>>();
			for(int i=0;i<temp.length;i++){
				lo.addOperator(wrapResource(temp[i]));
			}
			return lo;
		}else if(str.indexOf(EvalConst.FENGS)!=-1
				&&str.indexOf(":")!=-1){
			String[] li=str.split(EvalConst.FENGS);
			MapOperator<Operator<?>> mo=new MapOperator<Operator<?>>();
			for(String lis:li){
				String key=lis.substring(0,lis.indexOf(":"));
				String value=lis.substring(lis.indexOf(":")+1,lis.length());
				mo.putOperator(wrapResource(key), wrapResource(value));
			}
			return mo;
		}else if(str.indexOf(":")!=-1){
			String key=str.substring(0,str.indexOf(":"));
			String value=str.substring(str.indexOf(":")+1,str.length());
			return new MapOperator<Operator<?>>().putOperator(wrapResource(key), wrapResource(value));
		}else if(isNumber(str)){
			return new NumberOperator(str);
		}else if(isChar(str)){
			return new StringOperator(str.substring(1,str.length()-1));
		}else if(isCharacter(str)){
			return new StringOperator(str.substring(2,str.length()-2));
		}else{
			try {
				return new ClassOperator(Thread.currentThread().getContextClassLoader().loadClass(str));
			}catch (java.lang.Throwable e) {
				return new StringOperator(str);
			}
		}
	}
	
	
	public static boolean isNumber(String str){
		return NumberUtils.isNumber(str);
	}
	
	public static boolean isChar(String str){
		if(str.startsWith("\'")&&str.endsWith("\'")) return true;
		return false;
	}
	
	
	public static boolean isCharacter(String str){
		if(str.startsWith("\"")&&str.endsWith("\"")) return true;
		return false;
	}
	
	
	public static boolean hasFName(VisitorUnit<?,?> unit){
		if(unit.getfName()!=null
				&&!"".equals(unit.getfName())
				&&!Parenthesis.class.getName().equals(unit.getfName())
				&&!Bracket.class.getName().equals(unit.getfName())
				&&!Brace.class.getName().equals(unit.getfName())){
			return true;
		}
		return false;
	}
	//=================================

	/**
	 * 转化为中序序列
	 * @param expression
	 * @return
	 */
	public static java.util.List<String> toMiddleList(String expression){
		java.util.StringTokenizer st=new java.util.StringTokenizer(expression,OpEnum.getOpsString(),true);
		Stack<String> exp = new Stack<String>();
		exp.push("");
		boolean isFirst=true;
	    while (st.hasMoreTokens()) {
	    	String token=st.nextToken().trim();
	    	if(isFirst&&OpEnum.isOp(EvalConst.SHARP+token)){
    			exp.push(EvalConst.SHARP+token);
	    	}else{
		    	String pre=exp.peek();
		    	String temp=pre+token;
		    	
		    	if(OpEnum.isOp(temp)){
		    		exp.pop();
		    		exp.push(temp);
		    	}else if(OpEnum.isOp(pre)&&OpEnum.isOpString(token)){
		    		exp.push(EvalConst.SHARP+token);
		    	}else{
		    		exp.push(token);
		    	}
	    	}
	    	
	    	if(isFirst) isFirst=false;
	    }
	    exp.remove(0);  
	    return exp;
	}
	
	
	/**
	 * 中序转化为逆波兰式
	 * @param in
	 * @return
	 */
	public static java.util.List<Operator<?>> toBoland(List<String> in){
		Stack<OpEnum> stack=new Stack<OpEnum>();
		java.util.List<Operator<?>> list=new java.util.ArrayList<Operator<?>>();
		stack.push(OpEnum.EMP);
		for(String str:in){
			OpEnum op=OpEnum.fromString(str);
			 if(op!=null){
				 while(op.getPriority()<stack.peek().getPriority()){
					 list.add(new OperateOperator().setValue(stack.pop()));
				 }
				 stack.push(op);
			 }else{
				 list.add(smartWrapResource(str)); 
			 }
		}
		while(!stack.isEmpty()){
			list.add(new OperateOperator().setValue(stack.pop()));
		}
		list.remove(list.size()-1);
		return list;
	}
	
	
	
	/**
	 * 
	 * @param expression
	 * @return
	 */
	public static java.util.List<String> toBraceList(String expression){
		
		char[] chars=expression.toCharArray();
		java.util.Stack<String> st=new java.util.Stack<String>();
		java.util.List<String> list=new java.util.ArrayList<String>();
		java.lang.StringBuilder sb=new java.lang.StringBuilder("");
		for(int i=0;i<chars.length;i++){
			if(EvalConst.LEFTPARENTHESIS==chars[i]){
				sb.append(chars[i]);
				st.push(PlaceHolder.instance.getLeftParenthesisPlaceHolder());
				continue;
			}else if(EvalConst.RIGHTPARENTHESIS==chars[i]){
				sb.append(chars[i]);
				st.pop();
				continue;
			}else if(EvalConst.LEFTBRACE==chars[i]){
				if(!"".equals(sb.toString())) list.add(sb.toString());
				sb=new java.lang.StringBuilder("");
				sb.append(chars[i]);
				continue;
			} else if(EvalConst.RIGHTBRACE==chars[i]){
				sb.append(chars[i]);
				if(!"".equals(sb.toString())) list.add(sb.toString());
				sb=new java.lang.StringBuilder("");
				continue;
				
			} else if(st.isEmpty()&&EvalConst.COMA==chars[i]){
				if(!"".equals(sb.toString())) list.add(sb.toString());
				sb=new java.lang.StringBuilder("");
				continue;
			}
			sb.append(chars[i]);
		}
		if(!"".equals(sb.toString())) list.add(sb.toString());
	    return list;
	}

	//======================================
}
